import { globalEmitter, IEvent } from "@feng3d/event";
import { effect, reactive } from "@feng3d/reactivity";
import { WebSocketMessage } from "@feng3d/websocketmessage";
import { playerInfos } from "./client/data";
import "./client/FPSGame";
import { FPSGame } from "./client/FPSGame";

import { client } from "@feng3d/websocketclient";
import { webrtcData } from "./webrtc";

let fpsgame: FPSGame

// 页面加载时从localStorage获取上次登录的用户名和服务器地址
window.onload = function (): void
{
  const savedUsername = localStorage.getItem('lastUsername');
  const savedServerAddress = localStorage.getItem('lastServerAddress');
  const usernameInput = document.getElementById('username') as HTMLInputElement;
  const serverAddressInput = document.getElementById('serverAddress') as HTMLInputElement;
  if (savedUsername && usernameInput)
  {
    usernameInput.value = savedUsername;
  }
  if (savedServerAddress && serverAddressInput)
  {
    serverAddressInput.value = savedServerAddress;
  }
  usernameInput?.focus();
};

function login(): void
{
  const usernameInput = document.getElementById('username') as HTMLInputElement;
  const serverAddressInput = document.getElementById('serverAddress') as HTMLInputElement;
  const username = usernameInput?.value.trim();
  const serverAddress = serverAddressInput?.value.trim() || 'ws://localhost:8080';

  reactive(webrtcData).hostname = serverAddress.split('://').pop().split(':')[0];

  if (!username)
  {
    alert('请输入用户名');
    return;
  }

  // 保存用户名和服务器地址到localStorage
  localStorage.setItem('lastUsername', username);
  localStorage.setItem('lastServerAddress', serverAddress);

  reactive(client).serverAddress = serverAddress;
  reactive(client).username = username;

  // 发送数据
  reactive(client).sendData = {
    type: 'login',
    username: client.username
  };

  effect(() =>
  {
    reactive(client).message;

    if (client.message)
    {
      const data: WebSocketMessage = client.message;

      if (data.type === 'message')
      {
        addMessage(data.username, data.message);
      } else if (data.type === 'userList')
      {
        document.getElementById('login').style.display = 'none';
        document.getElementById('chat').style.display = 'block';
        // 初始化FPS游戏
        fpsgame = new FPSGame();
        fpsgame.init();
        //
        data.users.forEach(user =>
        {
          playerInfos.set(user.name, user);
          globalEmitter.emit('addPlayerToScene', user);
        });
        updateUserList();
      } else if (data.type === 'userJoined')
      {
        addMessage('系统', `${data.data.name} 加入了聊天`);
        playerInfos.set(data.data.name, data.data);
        globalEmitter.emit('addPlayerToScene', data.data);
        updateUserList();
      } else if (data.type === 'userLeft')
      {
        playerInfos.delete(data.username);
        updateUserList();
        globalEmitter.emit('removePlayerFromScene', data.username);
        addMessage('系统', `${data.username} 离开了聊天`);
      } else if (data.type === 'error')
      {
        alert(data.message);
        document.getElementById('login').style.display = 'block';
        document.getElementById('chat').style.display = 'none';
      } else if (data.type === 'update_player_info')
      {
        globalEmitter.emit(data.type, data);
      }
    }
  });

  // 处理断开连接
  effect(() =>
  {
    reactive(client).isClosed;

    if (client.isClosed)
    {
      addMessage('系统', '您已断开连接');
      document.getElementById('login').style.display = 'block';
      document.getElementById('chat').style.display = 'none';
    }
  });

  globalEmitter.on("send_to_server", onSend);
}

function onSend(event: IEvent<WebSocketMessage>): void
{
  const message = event.data;

  reactive(client).sendData = message;
}

function sendMessage(): void
{
  const messageInput = document.getElementById('message') as HTMLInputElement;
  const message = messageInput?.value;
  if (message)
  {

    reactive(client).sendData = {
      type: 'message',
      username: client.username,
      message: message
    };

    (document.getElementById('message') as HTMLInputElement).value = '';
    document.getElementById('message').blur();
  }
}

const usernameInput = document.getElementById('username') as HTMLInputElement;
usernameInput.addEventListener('keydown', (e: KeyboardEvent) =>
{
  if (e.key === 'Enter')
  {
    login();
  }
});

// 添加登录按钮事件监听
document.getElementById('loginButton').addEventListener('click', () =>
{
  login();
});

// 添加发送按钮事件监听
document.getElementById('sendButton').addEventListener('click', () =>
{
  sendMessage();
});
// 全局键盘事件监听
window.addEventListener('keydown', (e: KeyboardEvent) =>
{
  if (e.key === 'Enter' && document.getElementById('chat').style.display === 'block')
  {
    if (document.activeElement !== document.getElementById('message'))
    {
      document.getElementById('message').focus();
    } else
    {
      sendMessage();
      document.getElementById('message').blur();
    }
  }
});

const messageInput = document.getElementById('message') as HTMLInputElement;
messageInput.addEventListener('keydown', (e: KeyboardEvent) =>
{
  if (e.key === 'Enter')
  {
    sendMessage();
  }
});

function getUsernameColor(username: string): string
{
  if (username === 'System') return '#ff9800';

  let hash = 0;
  for (let i = 0; i < username.length; i++)
  {
    hash = username.charCodeAt(i) + ((hash << 7) - hash);
  }
  return `hsl(${Math.abs(hash % 360)}, 85%, 65%)`;
}

function addMessage(username: string, message: string): void
{
  const messages = document.getElementById('messages') as HTMLDivElement;
  const messageElement = document.createElement('div');

  const color = getUsernameColor(username);
  messageElement.innerHTML = `<strong style="color:${color}">${username}</strong><span style="color: #ffffff">:</span> ${message}`;
  messages.appendChild(messageElement);
  messages.scrollTop = messages.scrollHeight;
}

function updateUserList(): void
{
  const users = Array.from(playerInfos.keys());

  const userList = document.getElementById('users') as HTMLUListElement;
  userList.innerHTML = '';
  users.forEach(user =>
  {
    const li = document.createElement('li');
    const color = getUsernameColor(user);
    li.innerHTML = `<span style="color:${color}">${user}</span>`;
    userList.appendChild(li);

    li.addEventListener("click", async (e) =>
    {
      // Don't allow users to call themselves, because weird.
      if (user === client.username)
      {
        alert("I'm afraid I can't let you talk to yourself. That would be weird.");
        return;
      }

      reactive(webrtcData).remoteUsername = user;

    }, false);
  });
}
